#include "Middlewares/AUDIO_CODEC/music_lrc.h"
#include "Middlewares/FATFS/ff.h"
#include <string.h>
#include <stdio.h>

#define LRC_LINE_MAX 48

typedef struct
{
    FIL fil;                    /* FatFS 文件句柄 */
    char lineBuf[LRC_LINE_MAX]; /* 单行缓冲       */
    char outBuf[LRC_LINE_MAX];  /* 输出缓冲       */
    uint8_t opened;             /* 0/1 标志       */
} lrc_ctrl_t;

lrc_ctrl_t *g_lrc = NULL;

/* 解析 [mm:ss.xx] → 毫秒 */
/* 解析 [mm:ss.xx] 或 [mm:ss] → 毫秒 */
static char *parse_tag_ms(char *src, uint32_t *ms_out)
{
    int m, s, cs = 0; /* cs 初始化为 0 */
    char c;

    /* 先尝试带百分秒的完整格式 */
    if (sscanf(src, "[%d:%d.%d]", &m, &s, &cs) >= 2)
        goto ok;

    /* 再尝试只有分:秒的格式 */
    if (sscanf(src, "[%d:%d%c", &m, &s, &c) == 3 && c == ']')
        goto ok;

    return NULL; /* 两种都不符合 */

ok:
    *ms_out = (uint32_t)(m * 60000 + s * 1000 + cs * 10);
    char *p = strchr(src, ']');
    return (p && *(p + 1)) ? p + 1 : NULL;
}

void lrc_path_change(const char *src, char *dst)
{
    size_t len = strlen(src);

    /* 找到最后一个 '.' */
    char *dot = strrchr(src, '.');

    /* 如果找不到，或者点在路径分隔符之后，就认为没有后缀 */
    if (!dot || strchr(dot, '/'))
        dot = (char *)(src + len); /* 指向字符串结尾 */

    /* 拷贝基础名（不含旧后缀） */
    size_t base_len = dot - src;
    memcpy(dst, src, base_len);
    strcpy(dst + base_len, ".lrc");
}

uint8_t lrc_init(const char *path)
{
    if (g_lrc) /* 先释放旧句柄 */
        lrc_deinit();

    g_lrc = (lrc_ctrl_t *)lrc_malloc(sizeof(lrc_ctrl_t));
    if (!g_lrc)
        return 1;

    if (f_open(&g_lrc->fil, path, FA_READ) != FR_OK)
    {
        lrc_deinit();
        return 1;
    }
    g_lrc->opened = 1;
    return 0;
}

void lrc_deinit(void)
{
    if (!g_lrc)
        return; /* 空指针保护 */

    if (g_lrc->opened)
    {
        f_close(&g_lrc->fil);
        g_lrc->opened = 0;
    }
    vPortFree(g_lrc);
    g_lrc = NULL; /* 防止野指针 */
}

char *lrc_get_line_ms(uint32_t time_ms)
{
    if (!g_lrc || !g_lrc->opened)
        return "";

    f_lseek(&g_lrc->fil, 0);

    static char best_txt[LRC_LINE_MAX];
    uint32_t best_ms = 0;
    best_txt[0] = '\0';

    while (f_gets(g_lrc->lineBuf, sizeof(g_lrc->lineBuf), &g_lrc->fil))
    {
        g_lrc->lineBuf[strcspn(g_lrc->lineBuf, "\r\n")] = '\0';

        /* 1. 先把整行“纯歌词”抠出来（去掉所有 [xx:xx.xx]） */
        char *src = g_lrc->lineBuf;
        char clean[LRC_LINE_MAX];
        char *dst = clean;
        while (*src)
        {
            if (*src == '[' && strchr(src, ']'))
            {
                src = strchr(src, ']') + 1; /* 跳过时间戳 */
            }
            else
            {
                *dst++ = *src++;
            }
        }
        *dst = '\0'; /* clean 里就是“纯歌词” */

        /* 2. 再逐个解析时间戳，与纯歌词配对 */
        src = g_lrc->lineBuf;
        while (*src == '[')
        {
            uint32_t tag_ms;
            char *txt = parse_tag_ms(src, &tag_ms);
            if (!txt)
                break;

            if (tag_ms <= time_ms && tag_ms >= best_ms)
            {
                best_ms = tag_ms;
                strncpy(best_txt, clean, sizeof(best_txt) - 1);
                best_txt[sizeof(best_txt) - 1] = '\0';
            }

            src = strchr(src + 1, '[');
            if (!src)
                break;
        }
    }

    if (best_txt[0] == '\0') /* 如果歌词为空，则显示省略号 */
        strcpy(best_txt, "...");

    return best_txt;
}
